package user_dao

import (
	"fmt"
	"hft/Http/Models/dao"
	"hft/Http/Services/user/user_model"
	"regexp"

	"gorm.io/gorm"
)

type User struct{}

func (u *User) phone(phone string, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if phone == "" {
			return db
		}
		return db.Where("`hft_front_user`.`phone` LIKE ?", fmt.Sprintf("%v%%", phone))
	}
}
func (u *User) activityID(activityId int, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if activityId != 0 {
			return db.Where("FC.`activity_code` = ?", activityId)
		}
		return db
	}
}
func (u *User) search(account_region_link string, paginate *user_model.UserSearchParams, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Scopes(u.originName(paginate.OriginName, db)).Scopes(u.shield(paginate.IsShield, db)).Scopes(u.valid(paginate.Valid, db)).Scopes(u.level(paginate.Level, db)).Scopes(u.findLouPan(paginate.LouPanName, db)).Scopes(u.findLou(paginate.Region, account_region_link)).Scopes(u.phone(paginate.Phone, db)).Scopes(u.activityID(paginate.ActivityID, db)).Scopes(u.createTime(paginate.CreateTime, db)).Scopes(u.first_in_time(paginate.FirstInTime, db)).Scopes(u.lastUpdateTime(paginate.UpdateTime, db))
	}
}
func (u *User) originName(originName int, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if originName == 0 {
			return db
		} else {
			return db.Where("FC.`port` = ?", originName)
		}
	}
}
func (u *User) join(db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Scopes(u.joinClue(db))
	}
}
func (u *User) joinClue(db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Joins("LEFT JOIN `hft_front_clue` AS FC on `FC`.`user_id` = `hft_front_user`.`id`")
	}
}

func (u *User) selectWord(db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Select("`hft_front_user`.`is_shield`,`hft_front_user`.`first_clue_time`,`hft_front_user`.`update_time`,`hft_front_user`.`city_name`,`hft_front_user`.`level`,`hft_front_user`.`intend_lou`,`hft_front_user`.`is_valid`,`FC`.`ip`,`hft_front_user`.`newest_clue_time`,`FC`.`activity_name` as FC_activity_name, `FC`.`port` as FC_port ,hft_front_user.`username`,`hft_front_user`.`phone`,FC.`activity_code` as FC_activity_code,`hft_front_user`.`id`,`hft_front_user`.`create_time`,`hft_front_user`.`phone`,FC.`user_id` as FC_user_id")
	}
}
func (u *User) createTime(search_time []string, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if len(search_time) != 2 {
			return db
		}
		return db.Where(fmt.Sprintf("`hft_front_user`.`create_time` BETWEEN %v AND %v", search_time[0], search_time[1]))
	}
}
func (u *User) first_in_time(search_time []string, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if len(search_time) == 0 {
			return db
		}
		return db.Where(fmt.Sprintf("`hft_front_user`.`first_clue_time` BETWEEN %v AND %v", search_time[0], search_time[1]))
	}
}
func (u *User) lastUpdateTime(search_time []string, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if len(search_time) == 0 {
			return db
		}
		return db.Where(fmt.Sprintf("`hft_front_user`.`update_time` BETWEEN %v AND %v", search_time[0], search_time[1]))
	}
}
func (u *User) findLou(region string, account_region_link string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if ok, _ := regexp.MatchString(fmt.Sprintf("^%v", account_region_link), region); ok {
			return db.Where("`hft_front_user`.`city_link` LIKE ?", fmt.Sprintf("%v%%", region))
		}
		return db.Where("`hft_front_user`.`city_link` LIKE ?", fmt.Sprintf("%v%%", account_region_link))
	}
}
func (u *User) findLouPan(name string, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if name == "" {
			return db
		} else {
			return db.Where("`hft_front_user`.`intend_lou` LIKE ?", fmt.Sprintf("%v%%", name))
		}
	}
}
func (u *User) level(level string, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if level == "" {
			return db
		}
		return db.Where("hft_front_user.`level` = ?", level)
	}
}
func (u *User) valid(valid int, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if valid == -1 {
			return db
		}
		return db.Where("hft_front_user.`is_valid` = ?", valid)
	}
}
func (u *User) shield(is_shield bool, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if is_shield {
			return db.Where("hft_front_user.`is_shield` = ?", 1)
		}
		return db.Where("hft_front_user.`is_shield` = ?", 0)
	}
}

/* ------------------------ */
func (u *User) List(account_region_link string, paginate *user_model.UserSearchParams, db *gorm.DB) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Scopes(u.selectWord(db)).Scopes(u.join(db)).Scopes(u.search(account_region_link, paginate, db)).Group("`hft_front_user`.`id`").Order("hft_front_user.`create_time` desc").Scopes(dao.Paginate(dao.Page(paginate.Page), db))
	}
}

var UserDao = new(User)
